Python + Flask + Electron 混合开发入门 (项目演示) |
您所在的位置:网站首页 › flask 启动脚本 › Python + Flask + Electron 混合开发入门 (项目演示) |
写在前面
注: 如果您是第二次阅读本文, 推荐直接阅读 快速开始 章节以快速复现最终运行效果. 本文所涉及文件已存放在网盘空间: https://www.jianguoyun.com/p/DdlvwhwQ7t6sBxjJkcoB 欢迎下载使用. 概述本文是基于一个 python 开发者的角度, 尝试使用 electron 来开发桌面应用. 请注意本文只是一个面向新手的文章. 内容涉及 如何让 electron 调用起 python 模块, 以及 python 的数据如何传递到 electron 界面展示出来. 背景本文假设读者已具备以下能力: 有一定的 python 基础有少量的 javascript 知识 (能够写出 hello world 的程度)会用 npm init 初始化项目完成过 electron 的 hello world 类项目的启动本文假设读者已经做好以下准备: 安装 nodejs, npm, python 3 安装模块 (推荐安装在测试项目目录下): nodejs 模块: electron, python-shellpython 模块: flask 编辑器. vscode, pycharm, webstorm 都可以创建本次测试项目的目录, 比如我的项目路径为 “D:/workspace/test_room/electron_with_python/”, 后面将简称为 “electron_with_python” 或者 “本项目” 正文 1. 初始化项目通过 npm init 初始化项目. 得到的项目目录结构如下: D:/workspace/test_room/electron_with_python/ node_modules/ # 这是 npm 在本项目的模块安装目录 venv/ # 这是 python 在本项目的虚拟环境 (包含编译器, 本项目安装的模块等) index.html main.js package.json然后在本项目中通过 npm install 和 pip install 来安装 electron, python-shell, flask 模块. index.html, main.js, package.json 的源码见下面. 我尽量在保持易于阅读的基础上最简化 (注: 并非最终代码), 代码如下: index.html Welcome This is a python-electron app.main.js // 导入模块 const { app, BrowserWindow } = require("electron") // 创建窗口 function createWindow() { let win = new BrowserWindow({ // 设置一个宽为800, 高为600的窗口 width: 800, height: 600 }) // 加载本地的 index.html win.loadFile("index.html") } // 启动 app.on("ready", createWindow)package.json (注意 devDependencies 中要有 electron 和 python-shell 两个模块) { "name": "electron_with_python", "version": "1.0.0", "description": "Python + Flask + Electron 项目演示", "main": "main.js", "scripts": { "start": "electron ." }, "author": "Likianta", "license": "ISC", "devDependencies": { "electron": "^4.1.3", "python-shell": "^1.0.7" } }在命令行 cd 到本项目路径, 输入 npm start 启动, 大家看到的效果应该和下图一样: 2. 加入 python-shellpython-shell 是一个 nodejs 模块, 所以可以在 main.js 中导入并使用. python-shell 用于调用 python 写的 py 文件, 所以我们先在项目下新建一个 “hello.py” 文件: # ./hello.py # 里面就一句话 print("hello from python")然后修改 main.js 文件: const { app, BrowserWindow } = require("electron") // 创建窗口 function createWindow() { let win = new BrowserWindow({ width: 800, height: 600 }) win.loadFile("index.html") } // 从 python-shell 导入一个 PythonShell 对象 (注意大小写) const {PythonShell} = require("python-shell") // PythonShell 主要有 run() 和 runString() 两个方法, 这里我们用 run() // run() 第一个参数是要调用的 py 文件的路径 // 第二个参数是可选配置 (一般传 null) // 第三个参数是回调函数 PythonShell.run( "hello.py", null, function (err, results) { if (err) throw err console.log('hello.py finished') console.log('results', results) } ) // 启动 app.on("ready", createWindow)启动效果如下, 可以看到 main.js 中的两条 console.log() 都被触发成功: [外链图片转存失败(img-BBICF1p5-1563031004213)(https://i.loli.net/2019/04/11/5cae1716b40c2.png)] 这意味着到了这里, 我们已经实现了 electron 调用 python 模块的功能. 3. 加入 flask大家对 flask 可能比较陌生, 目前只需知道它是一个 python web 框架 (微服务) 就可以了. 既然是 web 框架, 就肯定有端口, 路由, html 渲染模板等东西. 在项目下新建一个 engine.py, 代码如下: from flask import Flask, render_template ''' 导入的这两个模块, Flask 是主体类, render_template 是渲染模板. ''' # 首先创建一个变量 app, 用于初始化 flask 启动核心 app = Flask(__name__) ''' 感兴趣的可以看一下它的源码, 当我们把 __name__ 传进去后, Flask 的实例化行为: (flask 源码) app.py -> Flask.__init__() (flask 源码) helpers.py -> _PackageBoundObject.__init__() 可以看到, Flask 会根据你传的 __name__ 定位到程序 (engine.py) 所在的根路径. 这个根路径的用处和 render_template 有关. 后面会讲. ''' @app.route('/') def homepage(): # 将本函数绑定到路由根地址, 这样我们访问主地址时, 就能看到这个页面 home = 'flask_welcome.html' # 还未创建, 接下来会写 return render_template(home) if __name__ == "__main__": # 启动, 启动后访问 http://127.0.0.1:5858 查看 app.run(host='127.0.0.1', port=5858)再在项目下创建一个 “flask_welcome.html” 文件, 代码如下: Welcome to Flask This is a homepage rendered by flask.现在我们尝试直接运行这个 py 文件看看效果: 不幸的是, 访问主页就报错了. 报错的原因在 pycharm 控制台可以看到, 显示 jinja2 没有找到模板文件: (这也是我喜欢 python 的原因之一, 报错容易诊断, 定位错误源方便.) jinja2 模块是 flask 默认使用的模板渲染引擎, 也就是 render_template(home) 这个函数, 之前我们还没有讲, 现在补充知识: Flask 默认会在程序根目录下的 templates 文件夹寻找要渲染的模板文件, 所以这里传入的模板文件的路径应是相对于 templates 目录的. 因此解决方法有两种, 要么想办法让 Flask 类的 template_folder 成员不要用 “templates” 作为模板目录入口, 要么就创建一个 templates 目录, 把 “flask_welcome.html” 放到里面. 第一种方法用一个自定义类继承于 Flask, 就可以任你发挥了, 当然这里我只演示第二种方法. 现在我们确认一下目录结构应该如下面所示: D:/workspace/test_room/electron_with_python/ node_modules/ templates/ flask_welcome.py venv/ engine.py hello.py index.html main.js package.json重新运行 engine.py, 在浏览器访问 http://127.0.0.1:5858/, 当如下图所示: [外链图片转存失败(img-IS3WOL2g-1563031004214)(https://i.loli.net/2019/04/11/5cae171deed22.png)] 4. python, flask, electron 混合与实现现在我们有了前三步的基础, 终于可以融会贯通了. 将 main.js 中的 “index.html” 改为 “templates/flask_welcome.html”, 把 “hello.py” 改为调用 “engine.py”, 来看看效果如何吧: // main.js const { app, BrowserWindow } = require("electron") // 创建窗口 function createWindow() { let win = new BrowserWindow({ width: 800, height: 600 }) // 加载 "templates/flask_welcome.html" win.loadFile("templates/flask_welcome.html") } // 使用 python-shell 调用 engine.py const {PythonShell} = require("python-shell") PythonShell.run( "engine.py", null, function (err, results) { if (err) throw err console.log('engine.py is running') console.log('results', results) } ) // 启动 app.on("ready", createWindow)[外链图片转存失败(img-dgAbTzHF-1563031004215)(https://i.loli.net/2019/04/11/5cae1720e1f0c.gif)] 以上就是 python + flask + electron 的项目演示. 快速开始注: 本节内容适合二次阅读的读者快速复习和复现. 初始化项目 创建项目: “D:/workspace/test_room/electron_with_python/” 项目目录结构: D:/workspace/test_room/electron_with_python/ node_modules/ templates/ flask_welcome.py venv/ engine.py hello.py index.html main.js package.json安装模块: npm install … : electron, python-shellpip install … : flask创建代码文件: 请从此网盘链接下载: https://www.jianguoyun.com/p/DdlvwhwQ7t6sBxjJkcoB下载此压缩包: “electron_with_python_20190411_000145.zip”(PS: 为保持压缩包体积, node_modules 和 venv 里的内容我都清空了.) 打开命令行, cd 到项目目录 输入 npm start, 运行本项目 效果应与下图一致: 扩展阅读TODO 注意事项 electron 的调试器端口不可以和 flask 相同, 否则会报错 参考 Using Electron with Flask and python-shell | Techiediaries https://www.techiediaries.com/flask-electron-tutorial/[李辉] Flask Web 开发实战 - 入门, 进阶与原理解析 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |